/*
 *MIT License
 *
 *Copyright (c) 2019 chenshuai cs4380@163.com
 *
 *Permission is hereby granted, free of charge, to any person obtaining a copy
 *of this software and associated documentation files (the "Software"), to deal
 *in the Software without restriction, including without limitation the rights
 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *copies of the Software, and to permit persons to whom the Software is
 *furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included in all
 *copies or substantial portions of the Software.
 *
 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *SOFTWARE.
 */

package com.cs.cslc.auth.service;

import com.cs.cslc.auth.utils.VerifyCodeUtils;
import com.cs.cslc.auth.vo.VerifyCodePicRes;
import com.cs.cslc.common.constant.RedisKeysConstant;
import com.cs.cslc.common.util.StringRedisHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * AuthService 授权验证服务.
 *
 * @author cs4380 https://gitee.com/xhbug_cs4380  cs4380@163.com
 * @version 1.0
 * @since 2021-12-14
 */
@Slf4j
@Service
public class AuthService {

    @Autowired
    private StringRedisHelper stringRedisHelper;

    /**
     * 获取验证码信息
     * <p>
     * 1.生成验证码（随机数4位）、验证码图片
     * 2.验证码令牌、验证码保存到redis中（在登录接口中校验该缓存数据）
     * </p>
     *
     * @return 验证码响应体
     */
    public VerifyCodePicRes findVerifyCode() {
        VerifyCodePicRes result = new VerifyCodePicRes();
        VerifyCodeUtils code = new VerifyCodeUtils();
        // 生成验证码图片
        BufferedImage image = code.getImage();
        // 获取验证码
        String verifyCode = code.getVerifyCode();

        // 验证码令牌的唯一标识
        String uuid = UUID.randomUUID().toString();
        String verifyCodeToken = RedisKeysConstant.LOGIN_VERIFY_CODE + uuid;
        // 添加到redis缓存中，key:验证码令牌,value:验证码,有效期为3分钟
        long timeout = 180;
        stringRedisHelper.set(verifyCodeToken, verifyCode, timeout);

        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            ImageIO.write(image, "png", bos);
            // 只返回uuid，减少数据体积
            result.setToken(uuid);
            // 进行base64编码
            result.setImage(Base64Utils.encodeToString(bos.toByteArray()));
            return result;
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return result;
    }

    /**
     * 验证码校验
     * <p>
     * 前端登录请求携带的验证码和保存到redis的验证码对比
     * </p>
     *
     * @param verifyCodeToken redis中存在的key
     * @param verifyCode      验证码
     * @return 匹配则返回null, 否则返回错误信息
     */
    public String verifyCodeCheck(String verifyCodeToken, String verifyCode) {
        if (StringUtils.isBlank(verifyCode) ||
                StringUtils.isBlank(verifyCodeToken)) {
            return "验证码不能为空！";
        }
        String value = stringRedisHelper.get(RedisKeysConstant.LOGIN_VERIFY_CODE + verifyCodeToken);
        // 验证码已过期
        if (null == value) {
            return "验证码已过期，请刷新后重试！";
        } else if (!verifyCode.equalsIgnoreCase(value)) {
            return "无效的验证码，请刷新后重试！";
        }
        return null;
    }
}
